#ifndef __THREADPOOL__
#define __THREADPOOL__

#include<thread>
#include<mutex>
#include<condition_variable>

#include<functional>
#include<queue>

const static size_t THREAD_NUM = 6;

typedef std::function<void()> TASK;

class ThreadPool
{
private:
	ThreadPool(size_t threadNum = THREAD_NUM)
		: _threadNum(threadNum)
	{}

	ThreadPool(const ThreadPool& tp) = delete;
	ThreadPool& operator=(const ThreadPool& tp) = delete;

public:
	static ThreadPool* GetInstance()
	{
		static std::mutex _instLock; // 直接搞一个静态锁
		if (_inst == nullptr)
		{
			std::unique_lock<std::mutex> ul(_instLock);
			if (_inst == nullptr)
			{
				_inst = new ThreadPool();
			}
		}

		return _inst;
	}

	void InitPool()
	{
		for (size_t i = 0; i < _threadNum; ++i)
		{
			std::thread(CallBack, this).detach(); // 创建线程直接detach，主线程不需要进行join等待
		}
	}

	void PushTask(TASK task)
	{ // 生产者生产，即往任务队列中push任务
		{
			std::unique_lock<std::mutex> ul(_mtx);
			// 不需要wait，没有设置capacity
			_q.push(task);
		}

		// 通知消费者消费
		_cv.notify_one();
	}

	void PopTask(TASK& task)
	{
		task = _q.front();
		_q.pop();
	}

	// 线程执行方法
	static void CallBack(void* arg)
	{
		ThreadPool* ptp = reinterpret_cast<ThreadPool*>(arg);
		while (true)
		{ // 死循环获取任务
			//等唤醒，唤醒就获取任务
			TASK task;
			{
				std::unique_lock<std::mutex> ul(ptp->_mtx);
				while (ptp->_q.empty()) ptp->_cv.wait(ul);

				// 条件成立，获取任务
				ptp->PopTask(task);
			}

			task();

		}
	}
	
private:
	size_t _threadNum;
	std::mutex _mtx;
	std::condition_variable _cv;
	std::queue<TASK> _q;
	static ThreadPool* _inst;
};

ThreadPool* ThreadPool::_inst = nullptr;

#endif
